package id.co.rho.scoring.cid.client.widgets;

import java.math.BigDecimal;
import java.math.RoundingMode;

import com.extjs.gxt.ui.client.event.Events;
import com.extjs.gxt.ui.client.event.FieldEvent;
import com.extjs.gxt.ui.client.event.Listener;
import com.extjs.gxt.ui.client.util.Util;
import com.google.gwt.user.client.Element;

import gxt.visual.ui.client.implementations.VNumberField;

public class DirtyAwareNumberField extends VNumberField implements DirtyAwareField {
	Listener changeListener = new Listener<FieldEvent>() {
	      public void handleEvent(FieldEvent be) {
	        onFieldChange(be);
	      }
	    };

	boolean dirtyPrevState = false;
	
	public DirtyAwareNumberField() {
		super();
		addListener(Events.Change, changeListener);	
	}

	@Override
	public void resetDirtyness() {
		dirtyPrevState = false;
		UIHelper.removeDirtyMarker(this);
		onFieldChange(null);
	}
	
	private void onFieldChange(FieldEvent be) {
		boolean dirty = isDirty();
		if(dirty != dirtyPrevState) {
			dirtyPrevState = dirty;
			if(dirty) {
				UIHelper.applyDirtyMarker(this);
			}else {
				UIHelper.removeDirtyMarker(this);
			}
		}
	}
	
	public boolean isDirty(){
		if (disabled || !rendered) {
		      return false;
		    }
		return !isEqual(getValue(), originalValue);
	}
	
	private boolean isEqual(Number val1, Number val2) {
		if(val1==null) val1 = BigDecimal.ZERO; // 0 and null is equal
		if(val2==null) val2 = BigDecimal.ZERO;
		
		//only Double and BigDecimal else Integer
		if(val2 instanceof Double){
			if(val1 instanceof BigDecimal){
				BigDecimal v1= (BigDecimal)val1;
				Double d1 = v1.doubleValue(); 
				return d1.compareTo((Double) val2)==0;
			}else{
				return (new Double(""+val1)).compareTo(new Double(""+val2))==0;
			}
		}else if(val2 instanceof BigDecimal) { 
			if(val1 instanceof Double){
				Double v1= (Double)val1;
				BigDecimal d1 = new BigDecimal(v1);
				return d1.compareTo((BigDecimal) val2)==0;
			}else{

                final BigDecimal _val1 = new BigDecimal("" + val1).setScale(11, RoundingMode.HALF_UP);
                final BigDecimal _val2 = new BigDecimal("" + val2).setScale(11, RoundingMode.HALF_UP);

                return _val1.toString().equals(_val2.toString());
			}
		}else{
			return (new Integer(""+val1)).compareTo(new Integer(""+val2))==0;
		}
		
    }
	
	@Override
    public void setMaxLength(int m) {
		 super.setMaxLength(m);
		 if (rendered) {
			 getInputEl().setElementAttribute("maxLength", m);
		 }
    }

    @Override
    protected void onRender(Element parent, int index) {
   	 super.onRender(parent, index);
   	 getInputEl().setElementAttribute("maxLength", getMaxLength());
    }

}
